package com.gtlab1207.br_security.services;

import com.taoyuanx.ca.core.bc.ProviderInstance;
import com.taoyuanx.ca.core.util.CertUtil;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.stereotype.Service;

import java.io.File;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.Calendar;
import java.util.Date;

/**
 * 生成CA证书业务层
 */
@Slf4j
@Service
public class CreateCaService {
    /**
     * 后续修改ca证书的基础路径为baseCertPath
     * */
    public static final String baseCertPath="/Users/shier/Documents/cert/rsa/"; //生成Cert基本路径
    static {
        Security.addProvider(ProviderInstance.getBCProvider());
        try {
            File baseFileDir=new File(baseCertPath);  //创建Cert目录
            File caDir=new File(baseCertPath+"ca");  //生成CA子目录路径
            if(!baseFileDir.exists()) {
                baseFileDir.mkdirs();
            }
            if(!caDir.exists()) {
                caDir.mkdirs();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // ca证书 的ca_cer_base64 地址
    static String caCert_base64=baseCertPath+"ca/ca_base64.cer";
    // ca证书的ca.cer地址
    static String caCert_cer=baseCertPath+"ca/ca.cer";
    // ca公钥的ca_pub.pem地址
    static String caPublicPath=baseCertPath+"ca/ca_pub.pem";
    // ca私钥的ca_pri.pem地址
    static String caPrivatePath=baseCertPath+"ca/ca_pri.pem";
    // 用户 p12 存储地址
    static String caPKCS12savepath=baseCertPath+"ca/ca.p12";
    //签发者DN
    static String issuerDN="O=nanjing, ST=man, EMAILADDRESS=2213352201@qq.com, T=salesman, C=client, UID=管理员, CN=DingJian, L=8, SURNAME=拾贰";
    //签名算法位数
    static Integer keySize=2048;

    /**
     * 这里创建CA的初始证书
     * @param alias
     * @param password
     * @throws Exception
     */
    public void createCACert(String alias,String password) throws Exception {
        Date notBefore=new Date();  //自动把当前日期和事件保存为其初始值
        BigInteger serialNumber=BigInteger.valueOf(1L);
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.YEAR, 1);//设置有效期为1年
        Date notAfter=instance.getTime();//获取证书截止日期
        String signHash="SHA1";
        String alg="RSA";
        CreateCA(issuerDN, notBefore, notAfter, serialNumber, signHash, alg,alias,password);
        // ca的私钥 ca的base64.cer 和用户证书DN
    }

    public void CreateCA(String userDN, Date notBefore, Date notAfter,
                             BigInteger serialNumber,String signHash,String alg,String alias,String password) throws Exception {
        KeyPair keyPair = CreateKeyPair();//创建一对SSH密钥对
        CertUtil.savePublicKeyPem(keyPair.getPublic(), caPublicPath);
        //生成公钥
        CertUtil.savePrivateKeyPem(keyPair.getPrivate(), caPrivatePath);
        //生成私钥
        X509Certificate makeUserSelfSignCert = CertUtil.makeUserSelfSignCert(keyPair.getPublic(), keyPair.getPrivate(), userDN,
                notBefore, notAfter, serialNumber, signHash.toUpperCase()+"WITH"+alg.toUpperCase());
        //根据userDN产生自签名证书
        CertUtil.saveX509CertBase64(makeUserSelfSignCert, caCert_base64);
        //生成cer格式用户证书
        CertUtil.savePKCS12(makeUserSelfSignCert, keyPair.getPrivate(), alias, password, caPKCS12savepath);
        //生成p12格式用户证书

    }//生成CA里的初始证书

    public static KeyPair CreateKeyPair() throws Exception {
        KeyPairGenerator kpg=kpg=KeyPairGenerator.getInstance("RSA", BouncyCastleProvider.PROVIDER_NAME);
        kpg.initialize(keySize);
        KeyPair keyPair = kpg.generateKeyPair();
        return keyPair;
    }

}
